﻿using Fluffy.Archive;
using Fluffy.FileMenuCommands;
using Fluffy.Library.DocumentContainer;
using Fluffy.Library.FileSources;
using System;
using System.IO;
using Fluffy.Text;
using Fluffy.Torrent;

namespace Fluffy
{
	internal class MainWindowModel
	{
		private readonly IDocumentContainer[] _documentContainers =
		{
			new ArchiveDocument(),
			new TorrentDocument(),
			new TextDocument(),
			new FakeDocument.FakeDocument() 
		};

		private readonly Lazy<OpenCommandModel> _openCommand;
		private readonly Lazy<NewCommandModel> _newCommand;

		private IFile _sourceFile;
		private DocumentViewModelBase _sourceFileContainer;

		public event Action FileSourceChanged;
		public event Action FileContainerRecreated;

		public MainWindowModel()
		{
			_openCommand = new Lazy<OpenCommandModel>(CreateOpenCommandModel);
			_newCommand = new Lazy<NewCommandModel>(CreateNewCommandModel);
		}

		public IFile SourceFile
		{
			get { return _sourceFile; }
		}

		public DocumentViewModelBase SourceFileContainer
		{
			get { return _sourceFileContainer; }
		}

		public OpenCommandModel OpenCommand
		{
			get { return _openCommand.Value; }
		}

		public NewCommandModel NewCommand
		{
			get { return _newCommand.Value; }
		}

		private OpenCommandModel CreateOpenCommandModel()
		{
			OpenCommandModel model = new OpenCommandModel();
			model.OpenFileAction += OnFileOpening;
			return model;
		}

		private NewCommandModel CreateNewCommandModel()
		{
			NewCommandModel model = new NewCommandModel();
			model.NewFileAction += OnFileOpening;
			return model;
		}

		private void OnFileOpening(IFile target)
		{
			OnFileOpening(target, GetSupportedContainer(target));
		}

		private void OnFileOpening(IFile target, IDocumentContainer container)
		{
			_sourceFile = target;

			if (_sourceFileContainer != null)
				_sourceFileContainer.Close();

			_sourceFileContainer = container.GenerateViewModel(target);
			
			if (FileContainerRecreated != null)
				FileContainerRecreated();

			if (FileSourceChanged != null)
				FileSourceChanged();
		}

		private IDocumentContainer GetSupportedContainer(IFile target)
		{
			for (int index = 0; index < _documentContainers.Length; index++)
			{
				IDocumentContainer container = _documentContainers[index];

				if (container.IsFileExtensionSupported(target))
				{
					return container;
				}
			}

			return new FakeDocument.FakeDocument();
		}

		public void ReopenAsAchive()
		{
			if (_sourceFileContainer is ArchiveDocumentViewModel)
				return;

			OnFileOpening(_sourceFile, new ArchiveDocument());
		}

		public void ReopenAsTorrent()
		{
			if (_sourceFileContainer is TorrentDocumentViewModel)
				return;

			OnFileOpening(_sourceFile, new TorrentDocument());
		}

		public void ReopenAsText()
		{
			if (_sourceFileContainer is TextDocumentViewModel)
				return;

			OnFileOpening(_sourceFile, new TextDocument());
		}
	}
}
